home *** CD-ROM | disk | FTP | other *** search
- Subject: v16i001: Multi-user conference system, Part01/04
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Keith Gabryelski <ucsd!elgar!ag>
- Posting-number: Volume 16, Issue 1
- Archive-name: conf2/part01
-
- Conf is a line oriented multi-user chat program designed to work on any
- SysV, BSD, or Xenix system.
-
- Conf has several advantages over the standard write program supplied
- with most Unix and Xenix operating systems.
- + Unlimited users conferencing at once.
- + 100 separate discussion lines.
- + Public and private messages in addition to password
- encrypted messages.
- + Quick and efficient user interaction.
- + User definable formats for messages.
- + Intelligent message display algorithm.
-
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # MANIFEST
- # Makefile
- # conf.c
- # conf.el
- export PATH; PATH=/bin:$PATH
- if test -f 'MANIFEST'
- then
- echo shar: will not over-write existing file "'MANIFEST'"
- else
- cat << \SHAR_EOF > 'MANIFEST'
- A Manifest Archived in
- ------------------------------------------------------------------------
- MANIFEST 1
- Makefile 1
- conf.c 1
- conf.el 1
- conf.h 2
- confalloc.c 2
- config.h 2
- confopts.c 2
- confprnt.c 3
- confrots.c 3
- confrw.c 3
- confsig.c 4
- confstr.c 4
- extern.h 4
- structs.h 4
- doc/READ_ME 5
- doc/conf.1 5
- doc/conf.txt 5
- doc/confhelp 5
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- cat << \SHAR_EOF > 'Makefile'
- SHELL=/bin/sh
- INSTALL= mv
- CFLAGS= -g
- SRCS= conf.c confrw.c confrots.c confopts.c confalloc.c confstr.c confprnt.c confsig.c
- OBJS= conf.o confrw.o confrots.o confopts.o confalloc.o confstr.o confprnt.o confsig.o
- HEADERS= conf.h config.h extern.h structs.h
- NEW= xconf
- NAME= conf
- LISP= conf.el
- MAKES= Makefile
- DOCDIR= doc
- CONFLIB= /usr/lib/conf
- CONFSPOOL= /usr/spool/conf
- BINDIR= /usr/local/bin
- LINT=lint
- OWNER=conf
- GROUP=conf
-
- LIBS= -ltermlib
-
- $(NEW): $(OBJS)
- $(CC) $(CFLAGS) -o $(NEW) $(OBJS) $(LIBS)
-
- all: $(NEW) install
-
- clean:
- rm -f *.o $(NEW) core
-
- shar:
- shar MANIFEST Makefile conf.c conf.el > confshar.1
- shar conf.h confalloc.c config.h confopts.c > confshar.2
- shar confprnt.c confrots.c confrw.c > confshar.3
- shar confsig.c confstr.c extern.h structs.h > confshar.4
- shar doc > confshar.5
-
- lint:
- $(LINT) $(LIBS) $(SRCS)
-
- install:
- cp $(NEW) $(BINDIR)/$(NAME)
-
- -mkdir $(CONFLIB)
-
- cp $(DOCDIR)/confhelp $(CONFLIB)
- -chgrp $(GROUP) $(CONFLIB) $(CONFLIB)/confhelp $(BINDIR)/$(NAME)
- -chown $(OWNER) $(CONFLIB) $(CONFLIB)/confhelp $(BINDIR)/$(NAME)
- -chmod u+s $(BINDIR)/$(NAME)
- -chmod 644 $(CONFLIB)/confhelp
- -chmod 755 $(CONFLIB)
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'conf.c'
- then
- echo shar: will not over-write existing file "'conf.c'"
- else
- cat << \SHAR_EOF > 'conf.c'
- #include "conf.h"
- /* Talk, talk ... it's all talk! */
-
- char *progname; /* program name (argv[0]) */
- char *logname, *homedir;
-
- int lfd, log_rfd, log_wfd, usr_fd;
- long ourplace;
- FILE *rec_fp;
- int confing = FALSE;
-
- char replyname[MAXNAMELEN] = "";
- char replytty[MAXTTYLEN+1] = ""; /* there is a reason for the + 1
- although I have forgotten it
- right now, I'm sure it should
- be there.
- */
-
- char *wrdata;
- unsigned wdlen=0;
-
- struct cusrfil cuser, tuser;
- struct clogfil clog, tlog;
-
- #ifdef SYSV
- struct termio term, saveterm;
- #endif SYSV
-
- #ifdef BSD
- struct tchars chrstr;
- struct sgttyb ktty;
- int ttyflags;
- #endif BSD
-
- char ichar = CTRL('C'); /* interrupt character */
- char qchar = CTRL('\\'); /* quit character */
-
- jmp_buf env;
-
- int columns = 80, lines = 24, banner = TRUE, seeme = TRUE, informe = FALSE,
- lineinput = FALSE, beep = FALSE, expand8bit = TRUE, expandctrl = TRUE;
-
- char *cls = NULL, *pager, *shell, *normform, *lineform, *shoutform, *sendform,
- *informform, *recfile;
-
- my_int()
- {
- longjmp(env, 1);
- }
-
- #ifdef BSD
- stopit()
- {
- ktty.sg_flags = ttyflags;
- stty(0, &ktty);
- (void) signal(SIGTSTP, SIG_DFL);
- (void) kill(0, SIGTSTP);
- gtty(0, &ktty);
- ttyflags = ktty.sg_flags;
-
- if (!(ttyflags&ECHO))
- lineinput = TRUE;
-
- ktty.sg_flags |= CBREAK;
- ktty.sg_flags &= ~ECHO;
- stty(0, &ktty);
-
- (void) ioctl(0, TIOCGETC, &chrstr);
-
- ichar = chrstr.t_intrc;
- qchar = chrstr.t_quitc;
- (void) signal(SIGTSTP, stopit);
- }
- #endif BSD
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- char *ptr, *word, *line, answer;
- int num, x, c, old_umask, rotten_egg;
- struct passwd *pt;
-
- progname = *argv++; --argc;
-
- /* Open all support files */
-
- old_umask = umask(0);
-
- x = 0;
- while ((lfd = open(CONFLOCK, O_CREAT|O_EXCL, 0666)) < 0)
- {
- if (++x > 60) /* looks like the lock file may be hosed */
- {
- printf("The lock file %s looks like it is wedged.\n", CONFLOCK);
- printf("What should I do; (A)bort, (C)ontinue, or (R)emove? ");
-
- answer = 'a';
-
- while (((c = getchar()) != '\n') && (c != CR))
- {
- switch(c)
- {
- case 'a':
- case 'A':
- case 'C':
- case 'c':
- case 'R':
- case 'r':
- answer = c;
- break;
-
- default:
- printf("\n(A)bort, (C)ontinue, or (R)emove? ");
- break;
- }
- }
-
- switch(answer)
- {
- case 'a':
- case 'A':
- (void) umask(old_umask);
- exit(-1);
-
- case 'c':
- case 'C':
- x = 0;
- continue;
-
- case 'r':
- case 'R':
- (void) unlink(CONFLOCK);
- continue;
- }
-
- sleep(1);
- }
- }
-
- close(lfd);
-
- if ((usr_fd = open(CONFUSERS, O_RDWR|O_CREAT, FILEMASK)) < 0)
- {
- (void) fprintf(stderr, "%s: couldn't open %s (%s)\n", progname,
- CONFUSERS, puterr(errno));
- (void) exit(-1);
- }
-
- (void) lseek(usr_fd, 0L, 0);
-
- if ((argc == 1) && (!strcmp(*argv, "-T")))
- {
- (void) lseek(usr_fd, 0L, 0);
-
- #ifdef SYSV
- lockf(usr_fd, F_LOCK, 0L); /* lock user file */
- #endif SYSV
-
- #ifdef BSD
- flock(usr_fd, LOCK_EX);
- #endif BSD
-
- rotten_egg = TRUE;
- while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
- sizeof(struct cusrfil))
- if (tuser.cu_flags != USER_OFF)
- {
- c = kill(tuser.cu_procid, 0);
- if ((!c) || ((c < 0) && (errno != ESRCH)))
- rotten_egg = FALSE;
- }
-
- #ifdef SYSV
- (void) lseek(usr_fd, 0L, 0);
- lockf(usr_fd, F_ULOCK, 0L);
- #endif SYSV
-
- #ifdef BSD
- flock(usr_fd, LOCK_UN);
- #endif BSD
-
- if (rotten_egg)
- {
- close(usr_fd);
- open(CONFLOG, O_TRUNC);
- open(CONFUSERS, O_TRUNC);
- }
-
- unlink(CONFLOCK);
- exit(0);
- }
-
- if ((log_wfd = open(CONFLOG, O_WRONLY|O_CREAT|O_APPEND, FILEMASK)) < 0)
- {
- (void) fprintf(stderr,"%s: couldn't create/open %s for writing(%s)\n",
- progname, CONFLOG, puterr(errno));
- (void) exit(-1);
- }
-
- (void) umask(old_umask);
-
- if ((log_rfd = open(CONFLOG, O_RDONLY)) < 0)
- {
- (void) fprintf(stderr,"%s: couldn't open %s for reading (%s)\n",
- progname, CONFLOG, puterr(errno));
- (void) exit(-1);
- }
-
- unlink(CONFLOCK);
-
- setuid(getuid());
-
- (void) lseek(log_rfd, 0L, 2);
-
- /* set up some pointers to interesting stuff */
-
- wrdata = mymalloc(wdlen = PAGESIZ);
-
- cuser.cu_line = 1;
- cuser.cu_flags = USER_ON;
- cuser.cu_procid = getpid();
-
- pt = getpwuid(getuid());
-
- if ((ptr = getlogin()) == NULL)
- if ((ptr = pt->pw_name) == NULL)
- ptr = "somebody"; /* can't figure this guy out */
-
- logname = mymalloc((unsigned)(strlen(ptr)+1));
- (void) strcpy(logname, ptr);
-
- (void) strcpy(cuser.cu_cname, ptr);
-
- if ((ptr = ttyname(0)) == NULL)
- strcpy(cuser.cu_tty, "tty??");
- else
- strcpy(cuser.cu_tty, ((ptr= strrchr(ptr, '/')) ? ptr+1 : "tty??"));
-
- homedir = mymalloc((unsigned)(strlen(pt->pw_dir)+1));
- (void) strcpy(homedir, pt->pw_dir);
-
- cls = mymalloc((unsigned)1);
- *cls = '\0';
-
- normform = mymalloc((unsigned)(sizeof(DEF_FORM_NORM)));
- (void) strcpy(normform, DEF_FORM_NORM);
-
- sendform = mymalloc((unsigned)(sizeof(DEF_FORM_SEND)));
- (void) strcpy(sendform, DEF_FORM_SEND);
-
- shoutform = mymalloc((unsigned)(sizeof(DEF_FORM_SHOUT)));
- (void) strcpy(shoutform, DEF_FORM_SHOUT);
-
- informform = mymalloc((unsigned)(sizeof(DEF_FORM_INFORM)));
- (void) strcpy(informform, DEF_FORM_INFORM);
-
- lineform = mymalloc((unsigned)(sizeof(DEF_FORM_LINE)));
- (void) strcpy(lineform, DEF_FORM_LINE);
-
- pager = mymalloc((unsigned)(sizeof(DEF_PAGER)));
- (void) strcpy(pager, DEF_PAGER);
-
- shell = mymalloc((unsigned)(sizeof(DEF_SHELL)));
- (void) strcpy(shell, DEF_SHELL);
-
- recfile = mymalloc((unsigned)(sizeof(DEF_RECFILE)));
- (void) strcpy(recfile, DEF_RECFILE);
-
- gettcap(); /* get termcap stuff */
- getrc(); /* get some defaults from rc file */
- getopts(); /* get some defaults from environment */
-
- while (word = *argv++, argc--)
- {
- if (*word == '-')
- {
- word++;
-
- while (*word != '\0')
- {
- switch(*word++)
- {
- case 'T':
- printf("%s: -T wasn't specified by itself. Ignoring...\n",
- progname);
-
- case 'l':
- if (*word == '\0')
- {
- if (!argc)
- {
- (void) printf("%s: -l switch specified without a conference line number\n",
- progname);
- usage();
- }
- word = *argv++; --argc;
- }
-
- num = atoi(word);
- if ((num < 1) || (num > MAXCONFLINES))
- {
- (void) printf("%s: invalid conference line number: %d\n",
- progname, num);
- usage();
- }
- cuser.cu_line = num;
- *word = '\0';
- break;
-
- case 's':
- if (*word == '\0')
- {
- if (!argc)
- {
- (void) fprintf(stderr,
- "%s: -s specified without a parameter\n",
- progname);
- usage();
- }
- word = *argv++; --argc;
- }
-
- if ((x = setopts(parsestr(word, strlen(word), NEXTWORD)))
- != FOUNDOPT)
- {
- char *errmess;
-
- if (x == AMBIGUOUS)
- errmess = "Ambiguous";
- else
- errmess = "Invalid";
-
- (void) fprintf(stderr, "%s: %s -s parameter: %s\n",
- progname, errmess, word);
- usage();
- }
- *word = '\0';
- break;
-
- case 'w':
- (void) do_who(0);
- (void) exit(0);
-
- default:
- (void)fprintf(stderr, "%s: invalid parameter '%c'\n",
- progname, *(word-1));
- usage();
- }
- }
- }
- else
- (void) do_ring(word);
- }
-
- /* by this point, all parameters/options have been parsed */
-
- confing = TRUE;
-
- clog.f_line = cuser.cu_line;
- clog.f_usrlen = strlen(cuser.cu_cname) + 1;
- clog.f_ttylen = strlen(cuser.cu_tty) + 1;
-
- (void) lseek(usr_fd, 0L, 0);
-
- #ifdef SYSV
- lockf(usr_fd, F_LOCK, 0L); /* lock user file */
- #endif SYSV
-
- #ifdef BSD
- flock(usr_fd, LOCK_EX);
- #endif BSD
-
- ourplace = lseek(usr_fd, 0L, 1);
- while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
- sizeof(struct cusrfil))
- if (tuser.cu_flags == USER_OFF)
- break;
- else
- ourplace = lseek(usr_fd, 0L, 1);
-
- (void) lseek(usr_fd, ourplace, 0);
-
- write(usr_fd, (char *)&cuser, sizeof(struct cusrfil));
-
- #ifdef SYSV
- (void) lseek(usr_fd, 0L, 0);
- lockf(usr_fd, F_ULOCK, 0L);
- #endif SYSV
-
- #ifdef BSD
- flock(usr_fd, LOCK_UN);
- #endif BSD
-
- /* any fatal errors pass this point must do a nice_exit(status) */
-
- write_log(INFORM, "Login", (char *)NULL, 0, (unsigned)strlen("Login"));
-
- #ifdef SYSV
- (void) ioctl(0, TCGETA, &term);
- saveterm=term;
-
- if (!(term.c_lflag&ECHO))
- lineinput = TRUE;
-
- ichar = term.c_cc[VINTR];
- qchar = term.c_cc[VQUIT];
-
- term.c_iflag &= ~(ICRNL);
- term.c_lflag &= ~(ICANON|ECHO);
- term.c_cc[VEOF] = 1;
- term.c_cc[VEOL] = 0;
- (void) ioctl(0, TCSETAW, &term);
-
- #endif SYSV
-
- #ifdef BSD
- gtty(0, &ktty);
- ttyflags = ktty.sg_flags;
-
- if (!(ttyflags&ECHO))
- lineinput = TRUE;
-
- ktty.sg_flags |= CBREAK;
- ktty.sg_flags &= ~ECHO;
- stty(0, &ktty);
-
- (void) ioctl(0, TIOCGETC, &chrstr);
-
- ichar = chrstr.t_intrc;
- qchar = chrstr.t_quitc;
- #endif BSD
-
- (void) signal(SIGINT, SIG_IGN);
- (void) signal(SIGQUIT, fatal);
- (void) signal(SIGHUP, nice_exit);
- (void) signal(SIGTERM, nice_exit);
- (void) signal(SIGILL, fatal);
- (void) signal(SIGTRAP, fatal);
- (void) signal(SIGIOT, fatal);
- (void) signal(SIGEMT, fatal);
- (void) signal(SIGFPE, fatal);
- (void) signal(SIGBUS, fatal);
- (void) signal(SIGSEGV, fatal);
- (void) signal(SIGSYS, fatal);
- (void) signal(SIGPIPE, fatal);
-
- #ifdef SIGTSTP
- (void) signal(SIGTSTP, stopit);
- #endif SIGTSTP
-
- if (banner)
- (void) version(FALSE);
-
- (void) printf("login user %s (%s) on conference line %d\n",
- cuser.cu_cname, cuser.cu_tty, cuser.cu_line);
-
- if (setjmp(env))
- {
- (void) signal(SIGINT, my_int);
- dispchar(ichar, stdout, NOVIS);
- (void) putchar('\n');
- (void) lseek(log_rfd, 0L, 2);
- }
- else
- (void) signal(SIGINT, my_int);
-
- forever
- {
- read_log();
-
- fflush(stdout); /* damnit */
- line = getline();
- (void) signal(SIGINT, my_int);
- if (line != NULL)
- {
- if ((*line == ':') && (*(line+1) != ':'))
- {
- if (*(line+1) == '!')
- keep_shell(line+2);
- else
- {
- --linelen;
- (void) intpret(line+1);
- }
- }
- else
- {
- if (*line == ':')
- write_log(NORMAL, line+1, (char *)NULL, 0, linelen-1);
- else
- write_log(NORMAL, line, (char *)NULL, 0, linelen);
- }
- free(line);
- }
- }
- }
-
- nice_exit(status)
- int status;
- {
- make_nice(TRUE);
-
- (void) signal(SIGALRM, SIG_DFL);
- (void) signal(SIGINT, SIG_DFL);
- (void) signal(SIGQUIT, SIG_DFL);
- (void) signal(SIGHUP, SIG_DFL);
- (void) signal(SIGTERM, SIG_DFL);
- (void) signal(SIGILL, SIG_DFL);
- (void) signal(SIGTRAP, SIG_DFL);
- (void) signal(SIGIOT, SIG_DFL);
- (void) signal(SIGEMT, SIG_DFL);
- (void) signal(SIGFPE, SIG_DFL);
- (void) signal(SIGBUS, SIG_DFL);
- (void) signal(SIGSEGV, SIG_DFL);
- (void) signal(SIGSYS, SIG_DFL);
- (void) signal(SIGPIPE, SIG_DFL);
-
- (void) exit(status);
- }
-
- make_nice(status)
- int status;
- {
- (void) alarm(0);
-
- if (status)
- write_log(INFORM,"Logout",(char *)NULL,0, (unsigned)strlen("Logout"));
-
- if (cuser.cu_flags&USER_RECORD)
- (void)fclose(rec_fp);
-
- cuser.cu_flags = USER_OFF;
- write_usr();
-
- (void) close(usr_fd);
- (void) close(log_rfd);
- (void) close(log_wfd);
-
- #ifdef SYSV
- (void) ioctl(0, TCSETAW, &saveterm);
- #endif SYSV
-
- #ifdef BSD
- ktty.sg_flags = ttyflags;
- stty(0, &ktty);
- #endif BSD
-
- execlp(progname, progname, "-T", (char *)0);
- }
-
- usage()
- {
- (void) fprintf(stderr,
- "usage: %s [-T][-w][-s switchname][-l line-number]\n",
- progname);
- (void) exit(-1);
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'conf.el'
- then
- echo shar: will not over-write existing file "'conf.el'"
- else
- cat << \SHAR_EOF > 'conf.el'
- ;; Run conf(1) as asynchronous inferior of Emacs.
- ;; provided by Michael Ditto (ford@kenobi.cts.com)
- ;; This file is not part of GNU Emacs.
-
- (defvar conf-process nil "The process of conf.")
-
- (defun conference (switches)
- "Conference with other users."
- (interactive "sArgs to conference (switches): ")
-
- (require 'shell)
-
- (let ((buffer (get-buffer-create "*conference*")))
- (switch-to-buffer buffer)
-
- (if (get-buffer-process buffer)
- (error "A conference process is already running"))
-
- (setq conf-process
- (start-process "conf" buffer
- "/bin/sh" "-c" (format "conf %s" switches))))
-
- (shell-mode)
- (turn-on-auto-fill)
- (setq mode-name "Conference")
- (set-marker (process-mark conf-process) (point-max))
- (set-process-filter conf-process 'conf-filter))
-
- (defun conf-filter (process string)
- (save-excursion
- (set-buffer (process-buffer process))
- (goto-char (process-mark process))
- (let ((start-line (point)))
- (insert-before-markers string)
- ;; (fill-region start-line (point))
- )
-
- (if (get-buffer-window (process-buffer process))
- nil
- (beep t))))
- SHAR_EOF
- fi # end of overwriting check
- # End of shell archive
- exit 0
- --
- "If green is all there is to be, then green is good enough for me" - ktf
- [ Keith ] UUCP: {ucsd, cbosgd!crash, sdcsvax!crash, nosc!crash}!elgar!ag
- [Gabryelski] INET: ag@elgar.cts.com ARPA: elgar!ag@ucsd.edu
-
-